package com.example.baiguangsystem.service.impl;

import com.example.baiguangsystem.entity.Book;
import com.example.baiguangsystem.entity.Section;
import com.example.baiguangsystem.mapper.BookMapper;
import com.example.baiguangsystem.service.BookService;
import com.example.baiguangsystem.vo.ResultType;
import lombok.NonNull;
import lombok.SneakyThrows;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.URLEncoder;
import java.util.List;

/**
 * 书本表service层实现
 *
 * @Author: 27641
 * @ProjectName: BaiGuangSystem
 * @Date: 2022/02/04/16:29
 * @noinspection SpellCheckingInspection
 */
@Service
public class BookServiceImpl implements BookService {

    /**
     * 注入依赖
     */
    @Autowired
    private BookMapper bookMapper;

    /**
     * 根据书本Id查找书本信息
     *
     * @param bookId 需要查找的书本Id
     * @return 查找结果
     */
    @Override
    public Book findBookById(Integer bookId) {
        return this.bookMapper.selectBookMessagesById(bookId);
    }

    /**
     * 根据书本名字查看书本信息
     *
     * @param bookName 需要查找的书本名字
     * @return 查找结果
     */
    @Override
    public Book findBookByName(String bookName) {
        return this.bookMapper.selectBookMessagesByName(bookName);
    }

    /**
     * 下载指定章节
     *
     * @param section  需要下载的章节
     * @param response 响应对象
     * @return 下载结果
     */
    @SneakyThrows
    @Override
    public boolean downloadSection(Section section, HttpServletResponse response) {
        String sectionPath = section.getSectionPath();
        File sectionFile = new File(sectionPath);
        FileInputStream inputStream = new FileInputStream(sectionFile);
        BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
        ServletOutputStream responseOutputStream = response.getOutputStream();
        if (sectionFile.exists()) {
            /*设置浏览器进行下载操作而不是打开*/
            response.setContentType("application/force-download");
            response.setHeader("Content-Type", "application/octet-stream;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;fileName=" +
                    URLEncoder.encode(section.getSectionName(), "UTF-8") + ".txt");
            byte[] bytes = new byte[1024];
            int length = -1;
            while (-1 != (length = bufferedInputStream.read(bytes))) {
                responseOutputStream.write(bytes, 0, length);
            }
            bufferedInputStream.close();
            responseOutputStream.flush();
            responseOutputStream.close();
            return true;
        }
        return false;
    }

    /**
     * 下载指定书本的全部章节
     *
     * @param list     所有章节信息
     * @param response 响应对象
     * @param bookId   下载章节所属的书本Id
     */
    @SneakyThrows
    @Override
    public void downloadAllSection(@NotNull List<Section> list, HttpServletResponse response, Integer bookId) {
        /*获取所属书本信息*/
        Book book = this.findBookById(bookId);
        response.setContentType("application/fore-download");
        response.setHeader("Content-Type", "application/octet-stream;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;fileName=" +
                URLEncoder.encode(book.getBookName(), "UTF-8") + ".txt");
        ServletOutputStream outputStream = response.getOutputStream();
        for (Section section : list) {
            File file = new File(section.getSectionPath());
            if (file.exists()) {
                FileInputStream inputStream = new FileInputStream(file);
                byte[] bytes = new byte[1024];
                int len = -1;
                while (-1 != (len = inputStream.read(bytes))) {
                    outputStream.write(bytes, 0, len);
                }
                inputStream.close();
            }
        }
        outputStream.flush();
        outputStream.close();
    }
}
